package xyz.hubery.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import xyz.hubery.domain.Market;
import xyz.hubery.domain.TradeArea;
import xyz.hubery.domain.UserFavoriteMarket;
import xyz.hubery.dto.MergeDepthDTO;
import xyz.hubery.dto.TradeAreaAndMarketDTO;
import xyz.hubery.dto.TradeAreaDTO;
import xyz.hubery.dto.TradeMarketDTO;
import xyz.hubery.enums.DepthMergeType;
import xyz.hubery.feign.CoinServiceFeign;
import xyz.hubery.mappers.TradeArearMappers;
import xyz.hubery.service.MarketService;
import xyz.hubery.service.TradeAreaService;
import xyz.hubery.mapper.TradeAreaMapper;
import org.springframework.stereotype.Service;
import xyz.hubery.service.UserFavoriteMarketService;
import xyz.hubery.vo.MergeDeptVo;
import xyz.hubery.vo.TradeAreaMarketVo;
import xyz.hubery.vo.TradeMarketVo;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author huber
 * @description 针对表【trade_area(交易区)】的数据库操作Service实现
 * @createDate 2025-10-16 07:45:08
 */
@Service
public class TradeAreaServiceImpl extends ServiceImpl<TradeAreaMapper, TradeArea>
        implements TradeAreaService {

    @Autowired
    private MarketService marketService;

    @Autowired
    private CoinServiceFeign coinServiceFeign;
    @Autowired
    private UserFavoriteMarketService userFavoriteMarketService;

    @Override
    public Page<TradeArea> findPage(Page<TradeArea> page, String name, Byte status) {
        return page(page, new LambdaQueryWrapper<TradeArea>()
                .eq(status != null, TradeArea::getStatus, status)
                .like(!StringUtils.isEmpty(name), TradeArea::getName, name)
                .orderByDesc(TradeArea::getLastUpdateTime)
        );
    }

    /**
     * 查询所有的交易区域以及市场
     *
     * @return
     */
    @Override
    public List<TradeAreaMarketVo> findTradeAreaMarket() {
        // 1、查询所有的交易区域
        List<TradeArea> tradeAreas = list(new LambdaQueryWrapper<TradeArea>().eq(TradeArea::getStatus, (byte) 1).orderByAsc(TradeArea::getSort));
        if (CollectionUtils.isEmpty(tradeAreas)) {
            return Collections.emptyList();
        }
        List<TradeAreaMarketVo> tradeAreaMarketVos = new ArrayList<TradeAreaMarketVo>();
        for (TradeArea tradeArea : tradeAreas) {
            // 2、查询 交易区域里面包含的市场
            List<Market> markets = marketService.getMarketsByTradeAreaId(tradeArea.getId());
            if (!CollectionUtils.isEmpty(markets)) {
                TradeAreaMarketVo tradeAreaMarketVo = new TradeAreaMarketVo();
                tradeAreaMarketVo.setAreaName(tradeArea.getName());
                tradeAreaMarketVo.setMarkets(marketsToVos(markets));
                tradeAreaMarketVos.add(tradeAreaMarketVo);
            }
        }
        return tradeAreaMarketVos;
    }

    /**
     * Market 转 TradeMarketVo
     *
     * @param markets
     * @return
     */
    private List<TradeMarketVo> marketsToVos(List<Market> markets) {
        return markets.stream().map(market -> toConvertVo(market)).collect(Collectors.toList());
    }

    /**
     * 将Market 转化为TradeMarketVo
     *
     * @param market
     * @return
     */
    private TradeMarketVo toConvertVo(Market market) {
        TradeMarketVo tradeMarketVo = new TradeMarketVo();
        tradeMarketVo.setImage(market.getImg()); // 报价货币的图片
        tradeMarketVo.setName(market.getName());
        tradeMarketVo.setSymbol(market.getSymbol());


        //TODO
        // 价格的设置
        tradeMarketVo.setHigh(market.getOpenPrice()); // OpenPrice 开盘价格
        tradeMarketVo.setLow(market.getOpenPrice()); // 获取K线数据
        tradeMarketVo.setPrice(market.getOpenPrice()); // 获取K线数据
        tradeMarketVo.setCnyPrice(market.getOpenPrice()); // 计算获得
        tradeMarketVo.setCoinCnyPrice(market.getOpenPrice()); // 计算获得
        tradeMarketVo.setPriceScale(market.getPriceScale()); // 价格保存的小数点

        // 获取报价货币
        Long buyCoinId = market.getBuyCoinId();
        String coinName = coinServiceFeign.getCoinName(buyCoinId);
        if (StringUtils.isEmpty(coinName)) {
            throw new IllegalArgumentException("市场配置错误，找不到对应的币种");
        }
        tradeMarketVo.setPriceUnit(coinName); // 报价货币的名称


        // 交易的额度
        tradeMarketVo.setTradeMin(market.getTradeMin());
        tradeMarketVo.setTradeMax(market.getTradeMax());

        // 下单的数量限制
        tradeMarketVo.setNumMin(market.getNumMin());
        tradeMarketVo.setNumMax(market.getNumMax());

        // 手续费的设置
        tradeMarketVo.setSellFeeRate(market.getFeeSell());
        tradeMarketVo.setBuyFeeRate(market.getFeeBuy());

        // 价格的小数的位数
        tradeMarketVo.setNumScale(market.getNumScale());


        //  排序
        tradeMarketVo.setSort(market.getSort());

        // 设置交易量
        tradeMarketVo.setVolume(BigDecimal.ZERO); // // 日的总交易量
        tradeMarketVo.setAmount(BigDecimal.ZERO); // 日的总的交易额


        // 设置涨幅
        tradeMarketVo.setChange(0.00);

        // 设置合并的深度
        tradeMarketVo.setMergeDepth(getMergeDepths(market.getMergeDepth()));

        return tradeMarketVo;
    }

    /**
     * 获取合并的深度
     *
     * @param mergeDepth
     * @return
     */
    private List<MergeDeptVo> getMergeDepths(String mergeDepth) {
        String[] split = mergeDepth.split(",");
        if (split.length != 3) {
            throw new IllegalArgumentException("合并深度不合法");
        }
        // 从小到大进行排序
        Arrays.sort(split, Comparator.comparingInt(Integer::valueOf));
        //  6(1/100000),5(100000),4 (10000)
        // 最小深度
        MergeDeptVo minMergeDeptVo = new MergeDeptVo();
        minMergeDeptVo.setMergeType("MIN"); //
        minMergeDeptVo.setValue(getDeptValue(Integer.valueOf(split[0])));


        MergeDeptVo defaultMergeDeptVo = new MergeDeptVo();
        defaultMergeDeptVo.setMergeType("DEFAULT"); //
        defaultMergeDeptVo.setValue(getDeptValue(Integer.valueOf(split[1])));

        MergeDeptVo maxMergeDeptVo = new MergeDeptVo();
        maxMergeDeptVo.setMergeType("MAX"); //
        maxMergeDeptVo.setValue(getDeptValue(Integer.valueOf(split[2])));

        List<MergeDeptVo> mergeDeptVos = new ArrayList<>();
        mergeDeptVos.add(minMergeDeptVo);
        mergeDeptVos.add(defaultMergeDeptVo);
        mergeDeptVos.add(maxMergeDeptVo);

        return mergeDeptVos;
    }

    //6  1/100000
    private BigDecimal getDeptValue(Integer scale) {
        BigDecimal bigDecimal = new BigDecimal(Math.pow(10, scale)); // Math.pow(10, scale) 指数操作
        return BigDecimal.ONE.divide(bigDecimal).setScale(scale, RoundingMode.HALF_UP); // 1/10^n
    }


    /**
     * 获取用户收藏的市场
     *
     * @param userId 用户ID
     * @return
     */
    @Override
    public List<TradeAreaMarketVo> getUserFavoriteMarkets(Long userId) {
        List<UserFavoriteMarket> userFavoriteMarkets = userFavoriteMarketService.list(new LambdaQueryWrapper<UserFavoriteMarket>()
                .eq(UserFavoriteMarket::getUserId, userId));
        if (CollectionUtils.isEmpty(userFavoriteMarkets)) {
            return Collections.emptyList();
        }
        List<Long> marketIds = userFavoriteMarkets.stream().map(UserFavoriteMarket::getMarketId).collect(Collectors.toList());
        List<Market> markets = marketService.listByIds(marketIds);
        List<TradeMarketVo> tradeMarketVos = marketsToVos(markets);
        TradeAreaMarketVo vo = new TradeAreaMarketVo();
        vo.setAreaName("我的收藏");
        vo.setMarkets(tradeMarketVos);
        return Arrays.asList(vo);
    }


    /**
     * 获取所有的交易区域及其管辖的交易市场
     *
     * @return
     */
    @Override
    public List<TradeAreaAndMarketDTO> listAreaAndMarkets() {
        List<TradeAreaAndMarketDTO> tradeAreaAndMarketDTOS = new ArrayList<>();
        // 获取所有的交易区域
        List<TradeAreaDTO> tradeAreaDTOS = list(new LambdaQueryWrapper<TradeArea>()).stream().map(TradeArearMappers.INSTANCE::toDto).collect(Collectors.toList());
        for (TradeAreaDTO tradeAreaDTO : tradeAreaDTOS) {
            // 根据交易区域id查询交易市场
            List<Market> marketList = marketService.getMarketsByAreaId(tradeAreaDTO.getId());
            List<TradeMarketDTO> tradeMarketDTOS = new ArrayList<>();
            for (Market market : marketList) {
                TradeMarketDTO marketDTO = market2TradeMarketDTO(market);
                tradeMarketDTOS.add(marketDTO);
            }
            TradeAreaAndMarketDTO dto = new TradeAreaAndMarketDTO();
            dto.setTradeAreaDTO(tradeAreaDTO);
            dto.setTradeMarketDTOS(tradeMarketDTOS);
            tradeAreaAndMarketDTOS.add(dto);
        }
        return tradeAreaAndMarketDTOS;
    }

    /**
     * 类型转换
     *
     * @param market
     * @return
     */
    private TradeMarketDTO market2TradeMarketDTO(Market market) {
        TradeMarketDTO marketDTO = new TradeMarketDTO();
        marketDTO.setSymbol(market.getName());
        marketDTO.setName(market.getName());
        marketDTO.setImage(market.getImg());
        marketDTO.setBuyFeeRate(market.getFeeBuy());
        marketDTO.setSellFeeRate(market.getFeeSell());
        marketDTO.setPriceScale(market.getPriceScale());
        marketDTO.setNumScale(market.getNumScale());
        marketDTO.setNumMin(market.getNumMin());
        marketDTO.setNumMax(market.getNumMax());
        marketDTO.setTradeMin(market.getTradeMin());
        marketDTO.setTradeMax(market.getTradeMax());
        marketDTO.setPrice(market.getOpenPrice());// TODO 当前价？
//        marketDTO.setPriceUnit(market.); // TODO 价格单位？
//        marketDTO.setCnyPrice(market.get); // TODO 当前价（人民币）？
//        marketDTO.setCoinCnyPrice(market.);     // TODO 报价货币人民币价格

        String[] depths = market.getMergeDepth().split(",");
        Arrays.sort(depths, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return Integer.parseInt(o1) - Integer.parseInt(o2);
            }
        });
        List<MergeDepthDTO> mergeDepthDTOS = new ArrayList<>();
        MergeDepthDTO mergeDepthDTO = new MergeDepthDTO();
        mergeDepthDTO.setMergeType(DepthMergeType.LOW.getCode());
        mergeDepthDTO.setValue(new BigDecimal(depths[0]));
        mergeDepthDTOS.add(mergeDepthDTO);

        MergeDepthDTO mergeDepthDTO1 = new MergeDepthDTO();
        mergeDepthDTO1.setMergeType(DepthMergeType.DEFAULT.getCode());
        mergeDepthDTO1.setValue(new BigDecimal(depths[1]));
        mergeDepthDTOS.add(mergeDepthDTO1);

        MergeDepthDTO mergeDepthDTO2 = new MergeDepthDTO();
        mergeDepthDTO2.setMergeType(DepthMergeType.HIGH.getCode());
        mergeDepthDTO2.setValue(new BigDecimal(depths[2]));
        mergeDepthDTOS.add(mergeDepthDTO2);

        marketDTO.setMergeDepth(mergeDepthDTOS);

        marketDTO.setHigh(market.getTradeMax());
        marketDTO.setLow(market.getTradeMin());
//        marketDTO.setVolume(market);    // TODO 日总交易量
//        marketDTO.setAmount(market);     // TODO 日总成交额
//        marketDTO.setChange(market);  // TODO 涨幅
        marketDTO.setSort(market.getSort());
        return marketDTO;
    }
}




